package com.sky.service.impl;

import com.sky.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.operator.Contain;
import com.ejlchina.searcher.operator.Equal;
import com.ejlchina.searcher.operator.InList;
import com.ejlchina.searcher.util.MapUtils;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.SetmealDTO;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.service.SetmealService;
import com.sky.utils.BeanCopyUtil;
import com.sky.utils.DateUtils;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealDishVo;
import com.sky.vo.SetmealVO;
import com.sky.web.page.TableSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author tzl
 * @Date 2023-07-15 11:38:24  星期六
 * @Description: 套餐接口业务实现类
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private BeanSearcher beanSearcher;

    @Autowired
    private SetmealDishMapper setmealDishMapper;


    @Override
    public SearchResult<SetmealVO> selectSetmeal(SetmealDTO dto) {
        Map<String, Object> build = MapUtils.builder()
                .page(TableSupport.buildPageRequest().getPageNum(),
                        TableSupport.buildPageRequest().getPageSize())
                .field(SetmealVO::getName,dto.getName()).op(Contain.class)
                .field(SetmealVO::getCategoryId,dto.getCategoryId()).op(Equal.class)
                .field(SetmealVO::getStatus,dto.getStatus()).op(Equal.class)
                .build();
        return beanSearcher.search(SetmealVO.class,build);
    }

    /**
     * 条件查询
     *
     * @param dto
     * @return
     */

    @Override
    public List<Setmeal> listAll(SetmealDTO dto) {
        Map<String, Object> build = MapUtils.builder()
                .field(Setmeal::getName,dto.getName()).op(Contain.class)
                .field(Setmeal::getCategoryId,dto.getCategoryId()).op(Equal.class)
                .field(Setmeal::getStatus,dto.getStatus()).op(Equal.class)
                .build();
        return beanSearcher.searchAll(Setmeal.class, build);
    }

    /**
     * 根据套餐id查询包含的菜品列表
     *
     * @param id 套餐id
     * @return
     */
    @Override
    public List<DishItemVO> getDishItemById(Long id) {
        Map<String, Object> build = MapUtils.builder()
                .field(DishItemVO::getSetmealId,id).op(Equal.class).
                build();
        return beanSearcher.searchAll(DishItemVO.class, build);
    }

    @Override
    public SetmealVO selectSetmealById(Long id) {
        Map<String, Object> build = MapUtils.builder()
                .field(SetmealVO::getId,id).op(Equal.class)
                .build();
        SetmealVO setmealVO = beanSearcher.searchFirst(SetmealVO.class, build);
        if (Objects.nonNull(setmealVO)) {
            Map<String, Object> build1 = MapUtils.builder()
                    .field(SetmealDish::getSetmealId,id).op(Equal.class)
                    .build();
            List<SetmealDish> setmealDishList = beanSearcher.searchAll(SetmealDish.class, build1);
            setmealVO.setSetmealDishes(setmealDishList);
        }
        return setmealVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSetmeal(SetmealDTO dto) {
        int result = 0;
        Setmeal setmeal = new Setmeal();
        BeanCopyUtil.copyProperties(dto,setmeal);
        setmeal.setCreateBy(BaseContext.getCurrentName());
        setmeal.setCreateTime(DateUtils.getNowDate());
        setmeal.setUpdateBy(BaseContext.getCurrentName());
        setmeal.setUpdateTime(DateUtils.getNowDate());
        result = setmealMapper.insert(setmeal);

        List<SetmealDish> setmealDishes = dto.getSetmealDishes();
        if (!CollectionUtils.isEmpty(setmealDishes)){
            setmealDishes.forEach(item ->{
                item.setSetmealId(setmeal.getId());
                item.setCreateBy(BaseContext.getCurrentName());
                item.setCreateTime(DateUtils.getNowDate());
                item.setUpdateBy(BaseContext.getCurrentName());
                item.setUpdateTime(DateUtils.getNowDate());
                setmealDishMapper.insert(item);
            });
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSetmeal(SetmealDTO dto) {
        int result;

        Setmeal setmeal = new Setmeal();
        BeanCopyUtil.copyProperties(dto,setmeal);
        setmeal.setUpdateBy(BaseContext.getCurrentName());
        setmeal.setUpdateTime(DateUtils.getNowDate());
        result = setmealMapper.updateById(setmeal);

        List<SetmealDish> setmealDishes = dto.getSetmealDishes();
        if(!CollectionUtils.isEmpty(setmealDishes)){
            List<Long> idList = setmealDishes.stream().map(SetmealDish::getId).filter(id -> id > 0).collect(Collectors.toList());
            setmealDishMapper.deleteBatchIds(idList);

            setmealDishes.forEach(item->{
                item.setSetmealId(setmeal.getId());
                item.setCreateBy(BaseContext.getCurrentName());
                item.setCreateTime(DateUtils.getNowDate());
                item.setUpdateBy(BaseContext.getCurrentName());
                item.setUpdateTime(DateUtils.getNowDate());
                setmealDishMapper.insert(item);
            });
        }
        return result;
    }

    /**
     * 修改套餐状态
     * @param dto 套餐信息
     * @return
     */
    @Override
    public int updateSetmealStatus(SetmealDTO dto) {
        Integer status = dto.getStatus();
        if (Objects.equals(status, StatusConstant.ENABLE)){
            Map<String, Object> build = MapUtils.builder()
                    .field(SetmealDishVo::getSetmealId,dto.getId()).op(Equal.class)
                    .build();
            List<SetmealDishVo> setmealDishVos = beanSearcher.searchAll(SetmealDishVo.class, build);
            if (!CollectionUtils.isEmpty(setmealDishVos)){
                setmealDishVos.forEach(item->{
                    if (StatusConstant.DISABLE.equals(item.getStatus())) {
                        throw new ServiceException(MessageConstant.SETMEAL_ENABLE_FAILED);
                    }
                });
            }
        }

        Setmeal setmeal = new Setmeal();
        BeanCopyUtil.copyProperties(dto,setmeal);
        setmeal.setUpdateBy(BaseContext.getCurrentName());
        setmeal.setUpdateTime(DateUtils.getNowDate());
        return setmealMapper.updateById(setmeal);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSetmealByIds(Long[] ids) {
        int result = 0;

        Map<String, Object> build = MapUtils.builder()
                .field(Setmeal::getId, Arrays.asList(ids)).op(InList.class)
                .field(Setmeal::getStatus, StatusConstant.ENABLE).op(Equal.class)
                .build();
        int i = beanSearcher.searchCount(Setmeal.class, build).intValue();
        if (i > 0){
            throw new ServiceException(MessageConstant.SETMEAL_ON_SALE);
        }

        //删除套餐表中的数据
        UpdateWrapper<Setmeal> wrapper = new UpdateWrapper<>();
        wrapper.in("id",(Object[]) ids);
        wrapper.set("del_flag","2");
        wrapper.set("update_time", DateUtils.getNowDate());
        wrapper.set("update_by", BaseContext.getCurrentName());
        result = result + setmealMapper.update(null,wrapper);

        //删除套餐菜品关系表中的数据
        UpdateWrapper<SetmealDish> wrapper1 = new UpdateWrapper<>();
        wrapper1.in("setmeal_id",(Object[]) ids);
        wrapper1.set("del_flag","2");
        wrapper1.set("update_time", DateUtils.getNowDate());
        wrapper1.set("update_by", BaseContext.getCurrentName());
        result = result + setmealDishMapper.update(null,wrapper1);

        return result;
    }
}
